package com.wzy.authority.security;


import com.wzy.authority.security.authentication.MyAuthenticationFailureHandler;
import com.wzy.authority.security.authentication.MyAuthenticationSuccessHandler;
import com.wzy.authority.security.authentication.MyLogoutSuccessHandler;
import com.wzy.authority.security.authentication.RestAuthenticationAccessDeniedHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.annotation.Resource;

/**
 * @program: authorityManagement
 * @description: spring-security  权限验证配置
 * @author: 1
 * @create: 2020-03-24 20:18
 **/
@Slf4j
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UserDetailsService userDetailsServiceImpl;

    @Resource
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

    @Resource
    private MyAuthenticationFailureHandler myAuthenticationFailureHandler;

    @Resource
    private RestAuthenticationAccessDeniedHandler restAuthenticationAccessDeniedHandler;


    @Resource
    private MyLogoutSuccessHandler myLogoutSuccessHandler;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        log.info("AuthenticationManagerBuilder 做出反应");
        //让验证逻辑走我们自己流程   并且加密方式选用BCryptPasswordEncoder
        auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder);
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        log.info("HttpSecurity 做出反应");

        //不运行跨域请求
        http.csrf().disable();


        http.authorizeRequests()
                //放行静态资源
                //注意：这里的资源还是  “/” 代表了 “static”
                .antMatchers(
                        "/login.html",
                        "/my/**",
                        "/treetable-lay/**",
                        "/js/**",
                        "/css/**",
                        "/fonts/**",
                        "/images/**",
                        "/lib/**",
                        "/ztree/**"
                )
                .permitAll()
                //任意请求都需要校验
                .anyRequest()
                .authenticated();

        //解决iframe弹窗问题  X-Frame-Options DENY问题
        http.headers().frameOptions().sameOrigin();

        //配置自定义登录页面
        http.formLogin()
                //使用的是springMvc拦截  所以这里指向的login.html并不是指向templates/login.html
                //而是指向控制器的/login.html
                .loginPage("/login.html")
                //登录接口 指向templates/login.html页面登录时请求的接口
                .loginProcessingUrl("/login")
                //成功处理方法类
                .successHandler(myAuthenticationSuccessHandler)
                //失败处理方法类
                .failureHandler(myAuthenticationFailureHandler)
                .and()
                //登出配置
                .logout()
                .permitAll()
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
                .logoutSuccessHandler(myLogoutSuccessHandler);


        //异常处理
        http.exceptionHandling().accessDeniedHandler(restAuthenticationAccessDeniedHandler);

    }
}
